package com.itshare.video.common.config.resolver;

import com.itshare.video.common.annontation.FormData;
import com.itshare.video.common.aop.AopPropertyUtils;
import com.itshare.video.common.aop.xss.annontation.CleanXSS;
import com.itshare.video.common.core.constant.enums.ApiInfo;
import com.itshare.video.common.exception.RequestBodyErrorException;
import com.itshare.video.common.util.ValidateUtils;
import com.itshare.video.common.util.XssUtil;
import com.itshare.video.common.web.WebUtil;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Validator;
import java.lang.reflect.Field;

/**
 * @Author lyr
 * @create 2020/10/24 9:56
 */
@Lazy
@Component
public class FormDataResolver implements HandlerMethodArgumentResolver {


    //
    @Resource
    private ValidateUtils validate;

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(FormData.class);
    }

    /**
     * 获取 FormData 的参数，或者 直接将 多个参数封装对象
     * @param methodParameter
     * @param modelAndViewContainer
     * @param nativeWebRequest
     * @param webDataBinderFactory
     * @return
     * @throws Exception
     */
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest request = (HttpServletRequest) nativeWebRequest.getNativeRequest();
        Class<?> clazz = methodParameter.getParameterType();
        Object formData = WebUtil.getForm(request,clazz);
        if (formData==null) {
            throw new RequestBodyErrorException(ApiInfo.BAD_REQUEST);
            // return null;
        }
        //如果要清除XSS
        if (methodParameter.hasParameterAnnotation(CleanXSS.class)  ||
                clazz.isAnnotationPresent(CleanXSS.class)) {
            //存在 安全注解，进行转义
            if (AopPropertyUtils.isJavaApi(clazz)) {
                if (formData instanceof  String) {
                    CleanXSS mark = methodParameter.getParameterAnnotation(CleanXSS.class);
                    return XssUtil.escapeJSAndHtml(mark, (String) formData);

                }
            }else {
                XssUtil.removeXSSWithBean(formData);
            }
        }
        //切面校验
        validate.doValidate(methodParameter,formData);
        return formData;

    }
}
